/**
 * This software was produced for the U. S. Government
 * under Contract No. FA8721-09-C-0002, and is
 * subject to the Rights in Noncommercial Computer Software
 * and Noncommercial Computer Software Documentation Clause
 * (DFARS) 252.227-7014 (JUN 1995)
 * 
 * (c) 2009 The MITRE Corporation. All Rights Reserved.
 *
 * SPMIF to OPNET Translator
 * Author: EWALTERS
 * Created: 11:07:22 AM, Jul 30, 2007
 * MITRE Corporation
 */
package com.mitre.spmif2opnet;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

import com.mitre.spmif2opnet.analysis.Priorities;

import gnu.getopt.*;

/**
 * This class is the repository for command-line option information.
 * We support the following command-line options:
 * 	-i <input file>
 *  -o <input file>
 *  -p <properties file>
 *  -P DIRECT | SCALED | ORDERED | RM] (Priority)
 *  -n (Generate OPNET Network)	
 *  -h (Print the help message)
 */
public class Options {
		
	/** 
	 * Input file - must be provided
	 */
	private String _input_fname;
	/**
	 * Output file - optional, can be constructed from input file name
	 */
	private String _output_fname;
	/**
	 *  Properties file - also optional
	 */
	private String _props_fname;
	/**
	 *  Flag - do we attempt to infer a network - this defaults to "false"
	 */
	private boolean _gen_network;
	/**
	 *  What kind of priorities do we want to track?
	 */
	private Priorities.PriorityType _ptype;
	/**
	 *  What and where are the Java properties we are going to deal with?
	 */
	private Properties _props;
	
	/**
	 * Master constructor
	 */
	public Options() {
		_input_fname = null;
		_output_fname = null;
		_props_fname = null;
		_gen_network = false;
		_ptype = Priorities.PriorityType.NO_PRIORITY;
		_props = new Properties();
	}
	
	/**
	 * Get the input file name as set by command-line args
	 * @return the input file name
	 */
	public String getInputFileName() {
		return _input_fname;
	}
	
	/**
	 * Get the output file name as set by command-line args
	 * @return the output file name
	 */
	public String getOutputFileName() {
		return _output_fname;
	}

	/**
	 * Get the properties file name as set by command-line args
	 * @return the properties file name
	 */
	public String getPropFileName() {
		return _props_fname;
	}
	
	/**
	 * Get whether or not to generate/infer the OPNET network
	 * @return the input file name
	 */
	public boolean genNetwork() {
		return _gen_network;
	}
	
	/**
	 * Return what kind of prorities we want to track
	 * See the Priorities.PriorityType enum for details
	 * @return the priority category
	 */
	public Priorities.PriorityType getPriorityType() {
		return _ptype;
	}
	
	/**
	 * Return the Java properties we loaded
	 * @return the properties
	 */
	public Properties getProperties() {
		return _props;
	}
	
	/**
	 * Command-line argument processing using getopt()
	 * @param exec_name name of the executable (spmif2opnet)
	 * @param args command-line arguments
	 * @return true - options acceptable, false - options bad, display usage
	 */
	public boolean getOptions(String exec_name, String[] args) {
		Getopt g = new Getopt(exec_name, args, "i:o:p:P:h:n");
		int inp_char;
		String arg;
		boolean response = true;
	
		while ((inp_char = g.getopt()) != -1) {
			switch(inp_char) {
			case 'i': 
				arg = g.getOptarg();
				if (arg == null) {
					response = false;
				} else {
					_input_fname = arg;
				}
				break;
			case 'o':
				arg = g.getOptarg();
				if (arg == null) {
					response = false;
				} else {
					_output_fname = arg;
				}
				break;
			case 'P':
				arg = g.getOptarg();
				if (arg == null) {
					response = false;
				} else {
					_ptype = Priorities.PriorityType.fromString(arg);
					if (_ptype == null) {
						response = false;
					}
				}
				break;
			case 'p':
				arg = g.getOptarg();
				if (arg == null) {
					response = false;
				} else {
					_props_fname = arg;
					try {
						_props.load(new FileInputStream(_props_fname));
					} catch (IOException exc) {
						System.out.println("Unable to locate properties file: " + _props_fname);
					}
				}
				break;
			case 'h':
				response = false;
				break;
			case 'n':
				_gen_network = true;
				break;
			default:
				System.out.println("Unknown option:" + inp_char);
				response = false;
			}
		}
			
		// Set up a default for the output name if it is not there 
		if (response && (_input_fname != null) && (_output_fname == null)) {
			int dot_index = _input_fname.lastIndexOf('.');
			_output_fname = _input_fname.substring(0, dot_index) 
				+ "_opnet" 
				+ _input_fname.substring(dot_index);
		}
		
		
		// Make sure that the input and output file names have been populated 
		if (response) {
			response = ((_input_fname != null) && (_output_fname != null)); 
		}
		return response;
	}

	/**
	 * Usage message
	 */
	public void usage() {
		System.out.println("Usage: spmif2opnet ");
		System.out.println("  -i <input file>");
		System.out.println(" [-o <output file>]");
		System.out.println(" [-p <OPNET properties file>]");
		System.out.println(" [-P DIRECT | SCALED | ORDERED | RM] (Priority)");
		System.out.println(" [-n] (Generate OPNET Network)");	
		System.out.println(" [-h] (Print this help message)");
	}	
}
